﻿//     Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Web.Mvc;
using Gateway.Console.Models.Validation;
using Microsoft.WindowsAzure.Subscriptions.Models;
using System.Security;
using System.Web;
using System.Text.RegularExpressions;
using Microsoft.Gateway.Utils;
using Microsoft.Gateway.Utils.Update;

namespace Gateway.Console.Models
{
    public class Deployment
    {
        public const string CreateAccountTag    = "CreateNew";
        public const string DividerTag          = "Divider";

        public Deployment()
        {
            DeploymentStatus = new List<DeployStatus>();
        }

        [Key]
        public int DeploymentId { get; set; }

        [Display(Name = "Service Name")]
        [Required]
        [Remote("CheckServiceNameAvailable", "Deployment", AdditionalFields = "SubscriptionSelection")]
        public string ServiceName { get; set; }

        [NotMapped]
        [Display(Name = "Deployment Subscription")]
        public IList<SubscriptionListOperationResponse.Subscription> Subscriptions { get; set; }
        
        public string RoleIndexConfigLocation { get; set; }

        [NotMapped]
        [Display(Name = "Deployment Region")]        
        public List<string> Regions { get; set; }

        [Display(Name = "Region")]
        public string RegionSelection { get; set; }

        [Display(Name = "Instance Count")]
        [Required]
        [RegularExpression(@"^[1-9][0-9]*$", ErrorMessage="Instance Count must be a number greater than 0")]
        public int InstanceCount { get; set; }

        [NotMapped]
        [Display(Name = "Storage Account")]
        public IEnumerable<Tuple<string, string>> StorageAccounts { get; set; }

        [Display(Name = "Storage Account")]
        public string SelectedStorageAccount { get; set; }

        [Display(Name = "Subscription")]
        public string SubscriptionSelection { get; set; }

        [NotMapped]
        [Display(Name = "Storage Account Name")]
        [ConditionalRequired(ValidationMethod = "ValidateConditionalCreateStorageAccount")]
        public string CreateStorageAccountName { get; set; }

        [NotMapped]
        [Display(Name = "Service Url")]
        public string ServiceUrl
        {
            get
            {
                return string.Format("http{0}://{1}.{2}", (IsHttpsEnabled) ? "s" : string.Empty, ServiceName, AzureEnvironment.AzureCloudServiceUriSuffix);
            }
        }

        public string ServicePackageFileLocation { get; set; }

        public string ServiceConfigTemplateLocation { get; set; }

        [NotMapped]
        public string StorageAccountKey { get; set; }

        [Display(Name = "Deployed Version")]
        public string DeployedVersion { get; set; }

        public virtual ICollection<DeployStatus> DeploymentStatus { get; set; }

        [NotMapped]
        public bool NoSubscriptions { get; set; }

        [Display(Name="Enable https")]
        public bool IsHttpsEnabled { get; set; }

        [NotMapped]
        [Display(Name="Gateway Certificate *.pfx")]
        [ConditionalRequired(ValidationMethod = "ValidateConditionalCertificate")]
        [CustomValidation(typeof(Deployment), "ValidateCertificateIsPfx")]
        public HttpPostedFileBase Certificate { get; set; }

        [NotMapped]        
        [Display(Name="Certificate Password")]
        [ConditionalRequired(ValidationMethod = "ValidateConditionalCertificate")]
        public String CertificatePassword { get; set; }

        public string CertificateThumbprint { get; set; }

        [NotMapped]
        public byte[] CertificateContents { get; set; }

        public bool OperationInProgress { get; set; }

        public string RefreshToken { get; set; }

        static bool ValidateConditionalCreateStorageAccount(object model)
        {
            return ((Deployment)model).SelectedStorageAccount != CreateAccountTag;
        }
        
        static bool ValidateConditionalCertificate(object model)
        {
            var deployment = (Deployment)model;
            return deployment.DeploymentId != 0 || !deployment.IsHttpsEnabled;
        }            

        public static ValidationResult ValidateCertificateIsPfx(HttpPostedFileBase cert, ValidationContext validationCtx)
        {
            var deployment = validationCtx.ObjectInstance as Deployment;

            if (deployment != null && deployment.IsHttpsEnabled && deployment.Certificate != null)
            {
                if (!Regex.IsMatch(cert.FileName, @".+\.pfx", RegexOptions.IgnoreCase))
                {
                    return new ValidationResult("Gateway Certificate must be in pfx format", new List<string> { "Certificate" });
                }
            }

            return ValidationResult.Success;
        }
    }
}